package com.xudu.xianrendongculturaltravelbackend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.xudu.xianrendongculturaltravelbackend.exception.ErrorCode;
import com.xudu.xianrendongculturaltravelbackend.exception.ThrowUtils;
import com.xudu.xianrendongculturaltravelbackend.manager.FileManager;
import com.xudu.xianrendongculturaltravelbackend.model.dto.file.UploadPictureResult;
import com.xudu.xianrendongculturaltravelbackend.model.dto.route.RouteAddRequest;
import com.xudu.xianrendongculturaltravelbackend.model.dto.route.RouteQueryRequest;
import com.xudu.xianrendongculturaltravelbackend.model.dto.route.RouteUpdateRequest;
import com.xudu.xianrendongculturaltravelbackend.model.dto.scenic.ScenicAddRequest;
import com.xudu.xianrendongculturaltravelbackend.model.entity.Route;
import com.xudu.xianrendongculturaltravelbackend.model.entity.Scenic;
import com.xudu.xianrendongculturaltravelbackend.model.entity.User;
import com.xudu.xianrendongculturaltravelbackend.model.vo.RouteVO;
import com.xudu.xianrendongculturaltravelbackend.model.vo.ScenicVO;
import com.xudu.xianrendongculturaltravelbackend.service.RouteService;
import com.xudu.xianrendongculturaltravelbackend.mapper.RouteMapper;
import com.xudu.xianrendongculturaltravelbackend.service.ScenicService;
import com.xudu.xianrendongculturaltravelbackend.service.UserService;
import dev.langchain4j.rag.query.router.LanguageModelQueryRouter;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Type;
import java.util.Date;
import java.util.List;

import static net.sf.jsqlparser.util.validation.metadata.MetadataContext.exists;

/**
 * @author xudu
 * @description 针对表【route】的数据库操作Service实现
 * @createDate 2025-06-17 20:02:06
 */
@Service
public class RouteServiceImpl extends ServiceImpl<RouteMapper, Route>
        implements RouteService {

    @Resource
    private UserService userService;

    @Resource
    private ScenicService scenicService;

    @Resource
    private FileManager fileManager;

    @Override
    public Long addRoute(RouteAddRequest routeAddRequest, HttpServletRequest request) {

        User loginUser = userService.getLoginUser(request);
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR);

        Route route = new Route();
        BeanUtils.copyProperties(routeAddRequest, route);
        route.setUserId(loginUser.getId());

        MultipartFile routeCoverImage = routeAddRequest.getRouteCoverImage();
        if (routeCoverImage != null) {
            UploadPictureResult routeCoverImageResult = fileManager.uploadPicture(routeCoverImage, "routeCoverImage");
            route.setRouteCoverImage(routeCoverImageResult.getUrl());
        }

        Gson gson = new Gson();
        // 处理标签
        List<String> routeTags = routeAddRequest.getRouteTags();
        String routeTagsJson = gson.toJson(routeTags);
        route.setRouteTags(routeTagsJson);

        // 处理景点
        // 判断添加的景点存在数据库中
        List<Long> alongScenics = routeAddRequest.getAlongScenics();
        for (Long alongScenic : alongScenics) {
            Scenic isExist = scenicService.getById(alongScenic);
            ThrowUtils.throwIf(isExist == null, ErrorCode.NOT_FOUND_ERROR);
        }
        String alongScenicsJson = gson.toJson(alongScenics);
        route.setAlongScenics(alongScenicsJson);

        boolean save = this.save(route);
        ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR);

        return route.getId();

    }

    @Override
    public List<RouteVO> getRouteVOList(RouteQueryRequest routeQueryRequest) {
        QueryWrapper<Route> routeQueryWrapper = this.getQueryWrapper(routeQueryRequest);

        List<Route> routeList = this.list(routeQueryWrapper);
        return routeList.stream().map(this::objToVo).toList();
    }


    @Override
    public Boolean updateRoute(RouteUpdateRequest routeUpdateRequest) {

        Route route = new Route();
        BeanUtils.copyProperties(routeUpdateRequest, route);

        MultipartFile routeCoverImage = routeUpdateRequest.getRouteCoverImage();
        if (routeCoverImage != null) {
            UploadPictureResult routeCoverImageResult = fileManager.uploadPicture(routeCoverImage, "routeCoverImage");
            route.setRouteCoverImage(routeCoverImageResult.getUrl());
        }

        Gson gson = new Gson();
        List<Long> alongScenics = routeUpdateRequest.getAlongScenics();
        String alongScenicsJson = gson.toJson(alongScenics);
        route.setAlongScenics(alongScenicsJson);

        List<String> routeTagsList = routeUpdateRequest.getRouteTags();
        String routeTagsListJson = gson.toJson(routeTagsList);
        route.setRouteTags(routeTagsListJson);

        boolean b = this.updateById(route);
        ThrowUtils.throwIf(!b, ErrorCode.OPERATION_ERROR);
        return true;
    }

    @Override
    public RouteVO objToVo(Route route) {
        RouteVO routeVO = new RouteVO();
        BeanUtils.copyProperties(route, routeVO);
        Gson gson = new Gson();

        // 处理景点
        String alongScenics = route.getAlongScenics();
        // List<Long> alongScenicsIdList = gson.fromJson(alongScenics, List.class);
        Type listType = new TypeToken<List<Long>>(){}.getType();
        List<Long> alongScenicsIdList = gson.fromJson(alongScenics, listType);
        List<ScenicVO> scenicVOList = alongScenicsIdList.stream().map(id -> {
            Scenic scenic = scenicService.getById(id);
            return Scenic.objToVo(scenic);
        }).toList();
        routeVO.setAlongScenics(scenicVOList);

        // 处理标签
        String routeTags = route.getRouteTags();
        List<String> routeTagsList = gson.fromJson(routeTags, List.class);
        routeVO.setRouteTags(routeTagsList);

        // 处理用户
        Long userId = route.getUserId();
        User user = userService.getById(userId);
        routeVO.setUserAccount(user.getUserAccount());


        return routeVO;
    }

    @Override
    public Page<RouteVO> getPageListRouteVo(RouteQueryRequest routeQueryRequest) {
        Page<Route> routePage = new Page<>(routeQueryRequest.getCurrent(), routeQueryRequest.getPageSize());
        Page<Route> routePageResult = this.page(routePage, this.getQueryWrapper(routeQueryRequest));
        Page<RouteVO> routeVOPage = new Page<>(routeQueryRequest.getCurrent(), routeQueryRequest.getPageSize(), routePageResult.getTotal());
        routeVOPage.setRecords(routePageResult.getRecords().stream().map(this::objToVo).toList());
        return routeVOPage;
    }

    @Override
    public QueryWrapper<Route> getQueryWrapper(RouteQueryRequest routeQueryRequest) {
        QueryWrapper<Route> routeQueryWrapper = new QueryWrapper<>();

        Long id = routeQueryRequest.getId();
        if (id != null){
            routeQueryWrapper.lambda().eq(Route::getId, id);
        }
        String routeName = routeQueryRequest.getRouteName();
        if (routeName != null){
            routeQueryWrapper.lambda().like(Route::getRouteName, routeName);
        }
        String spendTime = routeQueryRequest.getSpendTime();
        if (spendTime != null){
            routeQueryWrapper.lambda().like(Route::getSpendTime, spendTime);
        }
        String suitableTime = routeQueryRequest.getSuitableTime();
        if (suitableTime != null){
            routeQueryWrapper.lambda().like(Route::getSuitableTime, suitableTime);
        }
        String alongScenics = routeQueryRequest.getAlongScenics();
        if (alongScenics != null){
            routeQueryWrapper.lambda().like(Route::getAlongScenics, alongScenics);
        }
        String routeTags = routeQueryRequest.getRouteTags();
        if (routeTags != null){
            routeQueryWrapper.lambda().like(Route::getRouteTags, routeTags);
        }
        Integer routeStatus = routeQueryRequest.getRouteStatus();
        if (routeStatus != null){
            routeQueryWrapper.lambda().eq(Route::getRouteStatus, routeStatus);
        }
        // int current = routeQueryRequest.getCurrent();
        // int pageSize = routeQueryRequest.getPageSize();



        String userAccount = routeQueryRequest.getUserAccount();
        if (userAccount != null){
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.lambda().eq(User::getUserAccount, userAccount);
            User user = userService.getOne(userQueryWrapper);
            Long userId = user.getId();
            routeQueryWrapper.lambda().like(Route::getUserId, userId);
        }
        routeQueryWrapper.lambda().orderByDesc(Route::getId);
        return routeQueryWrapper;
    }
}




